#pragma once

#include <iostream>
#include <sys/epoll.h>
#include <cstring>
#include "log.hpp"
#include "Fail.hpp"
using namespace std;

//默认值
static const int default_size = 128; 

class Epoll
{
public:
    Epoll()
    {}

    //创建epoll模型
    void Create()
    {
        _epfd = epoll_create(default_size);
        //失败
        if(_epfd < 0)
        {
            log_message(Fatal, "epoll_create is error, errno: %d, strerror: %s", errno, strerror(errno));
            exit(EPOLL_CREATE_FAIL);
        }
    }
    
    //用户 -> 内核：关心哪个描述符的什么事件
    //增加、修改
    bool AddModEvent(int event, int fd, int op)
    {
        struct epoll_event data;
        data.events = event;
        data.data.fd = fd;
        int n = epoll_ctl(_epfd, op, fd, &data);

        if(n < 0)
        {
            log_message(Warning, "epoll_ctl is error, errno: %d, strerror: %s", errno, strerror(errno));
            return false;
        }
        
        return true;
    }

    void DelEvent(int fd)
    {
        epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr);
    }

    int Wait(struct epoll_event* data, int max, int timeout)
    {
        return epoll_wait(_epfd, data, max, timeout);
    }

    ~Epoll()
    {
        if(_epfd != default_size)
        {
            close(_epfd);
        }
    }

private:
    int _epfd; //epoll模型
};
